﻿using GrapeCity.Forguncy.Commands;
using Qdrant.Client.Grpc;
using QdrantConnector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Qdrant.Client.Grpc.Conditions;
using Range = Qdrant.Client.Grpc.Range;



public static class QdrantFilterBuilder
{
    public static async Task<Filter> BuildFilterAsync(IServerCommandExecuteContext dataContext, IEnumerable<QueryConditionObject> conditions)
    {
        var filter = new Filter();

        if (conditions != null)
        {

            foreach (var cond in conditions)
            {
                string key = (await dataContext.EvaluateFormulaAsync(cond.Name))?.ToString() ?? string.Empty;
                object val = await dataContext.EvaluateFormulaAsync(cond.Value);


                Condition condition = null;

                switch (cond.Op)
                {
                    case Operation.匹配:
                        condition = BuildMatchCondition(key, val);
                        filter.Must.Add(condition);
                        break;

                    case Operation.不匹配:
                        condition = BuildMatchCondition(key, val);
                        filter.MustNot.Add(condition);
                        break;

                    case Operation.在里面:
                        condition = BuildMatchAnyCondition(key, val);
                        filter.Must.Add(condition);
                        break;

                    case Operation.不在里面:
                        condition = BuildMatchAnyCondition(key, val);
                        filter.MustNot.Add(condition);
                        break;

                    case Operation.数值大于:
                        if (double.TryParse(val.ToString(), out double gt))
                        {
                            filter.Must.Add(Range(key, new Range { Gt = gt }));
                        }
                        break;

                    case Operation.数值不大于:
                        if (double.TryParse(val.ToString(), out double lte))
                        {
                            filter.Must.Add(Range(key, new Range { Lte = lte }));
                        }
                        break;

                    case Operation.数值小于:
                        if (double.TryParse(val.ToString(), out double lt))
                        {
                            filter.Must.Add(Range(key, new Range { Lt = lt }));
                        }
                        break;

                    case Operation.数值不小于:
                        if (double.TryParse(val.ToString(), out double gte))
                        {
                            filter.Must.Add(Range(key, new Range { Gte = gte }));
                        }
                        break;

                    case Operation.文本匹配:
                        filter.Must.Add(MatchText(key, val?.ToString() ?? string.Empty));
                        break;

                    case Operation.文本不匹配:
                        filter.MustNot.Add(MatchText(key, val?.ToString() ?? string.Empty));
                        break;

                    default:
                        throw new NotSupportedException($"Unsupported operation: {cond.Op}");
                }
            }
        }

        return filter;
    }

    private static Condition BuildMatchCondition(string key, object val)
    {
        switch (val)
        {
            case string s:
                return MatchKeyword(key, s);
            case bool b:
                return Match(key, b);
            case int i:
                return Match(key, i);
            case long l:
                return Match(key, l);
            default:
                // 其他类型通过 string 匹配
                return MatchKeyword(key, val?.ToString() ?? string.Empty);
        }
    }

    private static Condition BuildMatchAnyCondition(string key, object val)
    {
        // 支持逗号分隔字符串或 IEnumerable<object>，或单值
        IEnumerable<object> list = null;

        if (val is IEnumerable<object> eo) // 内置与其他插件
        {
            list = eo;
        }
        if (val is ArrayList al) // 对象与集合插件
        {
            list = al.ToArray();
        }
        else if (val is string s)
        {
            list = s.Split(',', StringSplitOptions.RemoveEmptyEntries)
                    .Select(x => x.Trim())
                    .Cast<object>();
        }
        else
        {
            list = new[] { val };
        }

        // 循环处理清单，将float、int、double等数值类型转换为long，其他的类型转换为string
        // 这里假设所有数值类型都可以转换为long，其他类型转换为string
        if (list == null || !list.Any())
        {
            return Match(key, new List<string>());
        }
        else if (list.Count() == 1)
        {
            // 如果只有一个元素，直接使用 Match
            var singleValue = list.First();
            return BuildMatchCondition(key, singleValue);
        }
        else if (list.All(x => x is string))
        {
            // 如果所有元素都是字符串，直接使用 MatchAny
            return Match(key, list.Cast<string>().ToList<string>());
        }
        else if (list.All(x => x is long) || list.All(x => x is int))
        {
            // 如果所有元素都是数值类型，转换为 long
            return Match(key, list.Cast<long>().ToList<long>());
        }
        else if (list.All(x => x is double) || list.All(x => x is float))
        {
            // 如果所有元素都是浮点数，转换为 long
            return Match(key, list.Cast<double>().Select(x => (long)x).ToList<long>());
        }
        else
        {
            // 否则，视同不处理。
            return Match(key, list.Select(x => x.ToString()).ToList<string>());
        }

    }
}
